home *** CD-ROM | disk | FTP | other *** search
/ SuperHack / SuperHack CD.bin / CODING / GRAPHICS / THREEDOM.ZIP / THREEDOM / WIN95.C < prev    next >
Encoding:
C/C++ Source or Header  |  1996-08-27  |  8.9 KB  |  386 lines

  1. /* @(#)win95.c 1.1   8/27/96 */
  2.  
  3. /******************************************************************************
  4. * Threedom: a 3D polygon renderer                                             *
  5. * (C) Copyright 1996 by Philip Stephens                                       *
  6. * (C) Copyright 1996 by the IBM Corporation                                   *
  7. * All Rights Reserved                                                         *
  8. *                                                                             *
  9. * Permission to use, copy, modify, and distribute this software and its       *
  10. * documentation without fee for any non-commerical purpose is hereby granted, *
  11. * provided that the above copyright notice appears on all copies and that     *
  12. * both that copyright notice and this permission notice appear in all         *
  13. * supporting documentation.                                                   *
  14. *                                                                             *
  15. * NO REPRESENTATIONS ARE MADE ABOUT THE SUITABILITY OF THIS SOFTWARE FOR ANY  *
  16. * PURPOSE.  IT IS PROVIDED "AS IS" WITHOUT EXPRESS OR IMPLIED WARRANTY.       *
  17. * NEITHER PHILIP STEPHENS OR IBM SHALL BE LIABLE FOR ANY DAMAGES SUFFERED BY  *
  18. * THE USE OF THIS SOFTWARE.                                                   *
  19. ******************************************************************************/
  20.  
  21. #define STRICT
  22. #define WIN32_LEAN_AND_MEAN
  23. #include <windows.h>
  24. #include <windowsx.h>
  25. #include <stdio.h>
  26. #include <stdarg.h>
  27. #include <string.h>
  28. #include "..\winlib\winlib.h"
  29. #include "typedef.h"
  30. #include "win95.h"
  31.  
  32. /*
  33.  * I don't care to hear about parameters or local variables that
  34.  * aren't used in a function.
  35.  */
  36. #pragma warn -aus
  37. #pragma warn -par
  38. #pragma warn -sig
  39.  
  40. static HWND main_window;
  41. static HWND bitmap_window;
  42. static HWND status_window;
  43. static fast_bitmap *bitmap_ptr = NULL;
  44. static RGBQUAD palette[256];
  45. static event_record event;
  46. static void (*event_proc_ptr)(event_record *event);
  47. static void (*work_proc_ptr)(void);
  48. static void (*quit_proc_ptr)(void);
  49.  
  50. /****************************************
  51.  * Function to destroy the main window. *
  52.  ****************************************/
  53.  
  54. static void
  55. destroy_main_window(HWND window_handle)
  56. {
  57.     PostQuitMessage(0);
  58.     (*quit_proc_ptr)();
  59. }
  60.  
  61. /**********************************
  62.  * Function to handle key events. *
  63.  **********************************/
  64.  
  65. static void
  66. process_key_event(HWND window_handle, UINT keycode, BOOL keydown, int repeat,
  67.           UINT flags)
  68. {
  69.     BOOL send_event;
  70.  
  71.     send_event = FALSE;
  72.     if (keydown)
  73.         switch(keycode) {
  74.         case VK_UP:
  75.             event.move = FORWARD;
  76.             send_event = TRUE;
  77.             break;
  78.         case VK_DOWN:
  79.             event.move = BACKWARD;
  80.             send_event = TRUE;
  81.             break;
  82.         case 'x':
  83.         case 'X':
  84.             event.move = LEFT;
  85.             send_event = TRUE;
  86.             break;
  87.         case 'c':
  88.         case 'C':
  89.             event.move = RIGHT;
  90.             send_event = TRUE;
  91.             break;
  92.         case VK_LEFT:
  93.             event.turn = TURNLEFT;
  94.             send_event = TRUE;
  95.             break;
  96.         case VK_RIGHT:
  97.             event.turn = TURNRIGHT;
  98.             send_event = TRUE;
  99.             break;
  100.         case 'a':
  101.         case 'A':
  102.             event.turn = LOOKUP;
  103.             send_event = TRUE;
  104.             break;
  105.         case 'z':
  106.         case 'Z':
  107.             event.turn = LOOKDOWN;
  108.             send_event = TRUE;
  109.             break;
  110.         case VK_SHIFT:
  111.             event.fast = TRUE;
  112.             break;
  113.         }
  114.     else
  115.         switch(keycode) {
  116.         case VK_UP:
  117.         case VK_DOWN:
  118.         case 'x':
  119.         case 'X':
  120.         case 'c':
  121.         case 'C':
  122.             event.move = NONE;
  123.             send_event = TRUE;
  124.             break;
  125.         case VK_LEFT:
  126.         case VK_RIGHT:
  127.         case 'a':
  128.         case 'A':
  129.         case 'z':
  130.         case 'Z':
  131.             event.turn = NONE;
  132.             send_event = TRUE;
  133.             break;
  134.         case VK_SHIFT:
  135.             event.fast = FALSE;
  136.             break;
  137.         }
  138.  
  139.     if (send_event)
  140.         (*event_proc_ptr)(&event);
  141. }
  142.  
  143. /***********************************************
  144.  * Function to handle gaining of window focus. *
  145.  ***********************************************/
  146.  
  147. static BOOL
  148. handle_window_focus(HWND window_handle)
  149. {
  150.     SetFocus(window_handle);
  151.     if (bitmap_ptr)
  152.         return(InstallFastBitmapPalette(bitmap_ptr));
  153.     return(FALSE);
  154. }
  155.  
  156. /*************************************************
  157.  * Function to process a command from a control. *
  158.  *************************************************/
  159.  
  160. void
  161. process_command_event(HWND window_handle, int menu_id, HWND control_handle,
  162.               UINT code_notify)
  163. {
  164.     char *world_file_name;
  165.  
  166.     switch(menu_id) {
  167.     case CM_OPEN:
  168.         if ((world_file_name = OpenFileDialog("Open Threedom world",
  169.                  "Threedom world (*.w3d)\0*.w3d\0")) != NULL) {
  170.             event.world_file_name = world_file_name;
  171.             (*event_proc_ptr)(&event);
  172.             event.world_file_name = NULL;
  173.         }
  174.         break;
  175.     case CM_EXIT:
  176.         PostQuitMessage(0);
  177.         (*quit_proc_ptr)();
  178.         break;
  179.     }
  180. }
  181.  
  182. /******************************************
  183.  * Function to start up graphics library. *
  184.  ******************************************/
  185.  
  186. void
  187. graphics_startup(char *program_name, void (*event_proc)(event_record *event),
  188.          void (*work_proc)(void), void (*quit_proc)(void),
  189.          HINSTANCE instance_handle)
  190. {
  191.     WinLibInit(instance_handle);
  192.     event_proc_ptr = event_proc;
  193.     work_proc_ptr = work_proc;
  194.     quit_proc_ptr = quit_proc;
  195.     event.move = NONE;
  196.     event.turn = NONE;
  197.     event.fast = FALSE;
  198.     event.resize = FALSE;
  199.     event.world_file_name = NULL;
  200. }
  201.  
  202. /*******************************************
  203.  * Function to shut down graphics library. *
  204.  *******************************************/
  205.  
  206. void
  207. graphics_shutdown(void)
  208. {
  209.     WinLibCleanUp();
  210. }
  211.  
  212. /***********************************
  213.  * Function to create main window. *
  214.  ***********************************/
  215.  
  216. /*
  217.  * List of event function handlers for main window.
  218.  */
  219. static event_callbacks callback_list = {
  220.     NULL,
  221.     destroy_main_window,
  222.     NULL,
  223.     NULL,
  224.     process_key_event,
  225.     NULL,
  226.     NULL,
  227.     handle_window_focus,
  228.     process_command_event
  229. };
  230.  
  231. /*
  232.  * Callback list for status window.
  233.  */
  234. static event_callbacks status_callback_list = {
  235.     NULL,
  236.     NULL,
  237.     NULL,
  238.     NULL,
  239.     NULL,
  240.     NULL,
  241.     NULL,
  242.     NULL,
  243.     NULL
  244. };
  245.  
  246. void
  247. create_window(int window_width, int window_height, char *window_title,
  248.           int window_state)
  249. {
  250.     /*
  251.      * Create a main window that is big enough to hold the bitmap and status
  252.      * windows.
  253.      */
  254.     main_window = CreateMainWindow(window_title, window_width + 30,
  255.                        window_height + 170, window_state,
  256.                        "menu", &callback_list);
  257.  
  258.     /*
  259.      * Create the bitmap window and status window.
  260.      */
  261.     bitmap_window = CreateChildWindow(main_window, 10, 10, window_width,
  262.                       window_height, WS_BORDER, NULL);
  263.     status_window = CreateEditControl(main_window, 10, window_height + 20,
  264.                       window_width, 100, WS_BORDER | ES_READONLY
  265.                       | ES_WANTRETURN, &status_callback_list);
  266. }
  267.  
  268. /**************************************
  269.  * Function to create a frame buffer. *
  270.  **************************************/
  271.  
  272. fbpixel *
  273. create_frame_buffer(int window_width, int window_height)
  274. {
  275.     int index;
  276.     int map;
  277.     float factor;
  278.     word red, green, blue;
  279.  
  280.     /*
  281.      * Create the logical palette.
  282.      */
  283.     index = FB_MAP_OFFSET;
  284.     for (map = 0, factor = 1.0; map < FB_MAPS; map++, factor *= 0.75)
  285.          for (red = 0; red < FB_REDS; red++)
  286.             for (green = 0; green < FB_GREENS; green++)
  287.                 for (blue = 0; blue < FB_BLUES; blue++) {
  288.                     palette[index].rgbRed = (BYTE)((red <<
  289.                         FB_RED_SHIFT) * factor);
  290.                     palette[index].rgbGreen = (BYTE)((green <<
  291.                         FB_GREEN_SHIFT) * factor);
  292.                     palette[index].rgbBlue = (BYTE)((blue <<
  293.                         FB_BLUE_SHIFT) * factor);
  294.                     index++;
  295.                 }
  296.  
  297.     /*
  298.      * Create the fast bitmap.
  299.      */
  300.     bitmap_ptr = CreateFastBitmap(bitmap_window, window_width, window_height,
  301.                       (RGBQUAD *)&palette, FB_COLOURS, FB_MAP_OFFSET);
  302.     (void)InstallFastBitmapPalette(bitmap_ptr);
  303.  
  304.  
  305.     /*
  306.      * Return a pointer to the bitmap array.
  307.      */
  308.     return((fbpixel *)bitmap_ptr->bits);
  309. }
  310.  
  311. /***************************************
  312.  * Function to display a frame buffer. *
  313.  ***************************************/
  314.  
  315. void
  316. display_frame_buffer(void)
  317. {
  318.     DisplayFastBitmap(bitmap_ptr);
  319. }
  320.  
  321. /***************************************
  322.  * Function to destroy a frame buffer. *
  323.  ***************************************/
  324.  
  325. void
  326. destroy_frame_buffer(void)
  327. {
  328.     DestroyFastBitmap(bitmap_ptr);
  329. }
  330.  
  331. /*************************
  332.  * Enter the event loop. *
  333.  *************************/
  334.  
  335. void
  336. enter_event_loop(void)
  337. {
  338.     EnterEventLoop(work_proc_ptr);
  339. }
  340.  
  341. /**********************************************
  342.  * Get the pixel index for a given RGB value. *
  343.  **********************************************/
  344.  
  345. pixel
  346. get_pixel(byte r, byte g, byte b)
  347. {
  348.     pixel index;
  349.     word red = (word)r << 8;
  350.     word green = (word)g << 8;
  351.     word blue = (word)b << 8;
  352.  
  353.     index = ((red & PIXEL_RED_MASK) >> PIXEL_RED_SHIFT) +
  354.         ((green & PIXEL_GREEN_MASK) >> PIXEL_GREEN_SHIFT) +
  355.         ((blue & PIXEL_BLUE_MASK) >> PIXEL_BLUE_SHIFT);
  356.     return(index);
  357. }
  358.  
  359. /*******************************************
  360.  * Display a message on the status screen. *
  361.  *******************************************/
  362.  
  363. void
  364. system_message(char *format, ...)
  365. {
  366.     va_list arg_ptr;
  367.     char oldmessage[1024];
  368.     char newmessage[2048];
  369.     char *old_ptr, *new_ptr;
  370.  
  371.     va_start(arg_ptr, format);
  372.     vsprintf(oldmessage, format, arg_ptr);
  373.     va_end(arg_ptr);
  374.  
  375.     old_ptr = oldmessage;
  376.     new_ptr = newmessage;
  377.     while (*old_ptr) {
  378.         if (*old_ptr == '\n')
  379.             *new_ptr++ = '\r';
  380.         *new_ptr++ = *old_ptr++;
  381.     }
  382.     *new_ptr = '\0';
  383.  
  384.     DisplayMessage(status_window, newmessage);
  385. }
  386.